﻿using netDxf;
using netDxf.Entities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Web;
using System.Web.Mvc;
using WebAPI_Cad.Models.AnalysisDXF;

namespace WebAPI_Cad.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Upload()
        {
            HttpFileCollection files = System.Web.HttpContext.Current.Request.Files;

            string BasePath = System.Web.HttpContext.Current.Server.MapPath("~/") + "File\\";

            string fullPath = BasePath + "\\" + files[0].FileName;

            if (!Directory.Exists(Path.GetDirectoryName(fullPath)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(fullPath));
            }

            //报错文件到本地磁盘
            files[0].SaveAs(fullPath);

            //数据解析
            string data = AnalysisDXF(fullPath);

            return Json(new { Data= data }, "text/html", JsonRequestBehavior.AllowGet);
        }

        #region DXF文件解析为画布文件

        List<double> listX = null;//所有X轴坐标
        List<double> listY = null;//所有Y轴坐标
        /// <summary>
        /// 将dxf文件转化为画布需要的文件保存在txt文件里面
        /// </summary>
        /// <param name="doc_dxf"></param>
        private string AnalysisDXF(string filePath)
        {
            var doc_dxf = DxfDocument.Load(filePath);
            listX = new List<double>();
            listY = new List<double>();
            MapInfo info = new MapInfo();
            List<object> list = new List<object>();
            if (doc_dxf != null)
            {
                //线
                if (doc_dxf.Lines.Any())
                {
                    foreach (netDxf.Entities.Line item in doc_dxf.Lines)
                    {
                        AddLine(list, item);
                    }
                }

                //圆
                if (doc_dxf.Circles.Any())
                {
                    foreach (netDxf.Entities.Circle item in doc_dxf.Circles)
                    {
                        AddCircle(list, item);
                    }
                }

                //文字
                if (doc_dxf.Texts.Any())
                {
                    foreach (netDxf.Entities.Text item in doc_dxf.Texts)
                    {
                        AddText(list, item);
                    }
                }

                //折线
                if (doc_dxf.LwPolylines.Any())
                {
                    foreach (netDxf.Entities.LwPolyline item in doc_dxf.LwPolylines)
                    {
                        AddLwPolyline(list, item);
                    }
                }

                //块
                if (doc_dxf.Inserts.Any())
                {
                    foreach (netDxf.Entities.Insert item in doc_dxf.Inserts)
                    {
                        foreach (var entity in item.Block.Entities)
                        {
                            if (entity.Type == EntityType.Line)
                            {
                                AddLine(list, entity as netDxf.Entities.Line, item);
                            }
                            else if (entity.Type == EntityType.Circle)
                            {
                                AddCircle(list, entity as netDxf.Entities.Circle, item);
                            }
                            else if (entity.Type == EntityType.LightWeightPolyline)
                            {
                                AddLwPolyline(list, entity as netDxf.Entities.LwPolyline, item);
                            }
                            else if (entity.Type == EntityType.Text)
                            {
                                AddText(list, entity as netDxf.Entities.Text, item);
                            }
                        }
                    }
                }

                info.Map = list;
                info.MaxX = listX.Max();
                info.MaxY = listY.Max();
                info.MinX = listX.Min();
                info.MinY = listY.Min();

            }
            return Newtonsoft.Json.JsonConvert.SerializeObject(info);
        }


        /// <summary>
        /// 画多边形
        /// </summary>
        /// <param name="list"></param>
        /// <param name="item"></param>
        /// <param name="insert"></param>
        private void AddLwPolyline(List<object> list, netDxf.Entities.LwPolyline item, Insert insert = null)
        {
            LwPplyline line = new LwPplyline();
            line.Type = item.Type.ToString();
            line.IsClose = item.IsClosed ? 1 : 0;
            bool flag = true;
            foreach (var point in item.Vertexes)
            {
                Vector3 vector = new Vector3 { X = point.Position.X, Y = point.Position.Y };
                if (!ConverPoint(vector, insert, out Models.AnalysisDXF.Point p))
                {
                    flag = false;
                }
                line.Points.Add(p);
            }

            if (flag)
            {
                list.Add(line);
            }
        }

        private void AddText(List<object> list, netDxf.Entities.Text item, Insert insert = null)
        {
            Models.AnalysisDXF.Text txt = new Models.AnalysisDXF.Text();
            txt.Type = item.Type.ToString();
            txt.Height = insert == null ? item.Height : item.Height * insert.Scale.X;
            txt.Value = item.Value;
            txt.Rotation = item.Rotation;
            if (ConverPoint(item.Position, insert, out Models.AnalysisDXF.Point p))
            {
                txt.Point = p;
                list.Add(txt);
            }
        }

        /// <summary>
        /// 坐标转换
        /// </summary>
        /// <param name="vector"></param>
        /// <param name="insert"></param>
        /// <param name="p"></param>
        /// <returns></returns>
        private bool ConverPoint(Vector3 vector, Insert insert, out Models.AnalysisDXF.Point p)
        {
            p = new Models.AnalysisDXF.Point()
            {
                X = vector.X,
                Y = vector.Y
            };

            //块元素特殊处理
            if (insert != null)
            {
                p.X = p.X * insert.Scale.X + insert.Position.X;
                p.Y = p.Y * insert.Scale.Y + insert.Position.Y;
            }
            listX.Add(p.X);
            listY.Add(p.Y);
            return true;
        }
        private void AddCircle(List<object> list, netDxf.Entities.Circle item, Insert insert = null)
        {
            if (ConverPoint(item.Center, insert, out Models.AnalysisDXF.Point p))
            {
                Models.AnalysisDXF.Circle line = new Models.AnalysisDXF.Circle();
                line.Type = item.Type.ToString();
                line.Radius = insert == null ? item.Radius : item.Radius * insert.Scale.X;
                line.Point = p;
                listX.Add(line.Point.X + line.Radius);
                listX.Add(line.Point.X - line.Radius);
                listY.Add(line.Point.Y + line.Radius);
                listY.Add(line.Point.Y - line.Radius);
                list.Add(line);
            }
        }

        private void AddLine(List<object> list, netDxf.Entities.Line item, Insert insert = null)
        {
            if (ConverPoint(item.StartPoint, insert, out Models.AnalysisDXF.Point StartPoint) && ConverPoint(item.EndPoint, insert, out Models.AnalysisDXF.Point EndPoint))
            {
                Models.AnalysisDXF.Line line = new Models.AnalysisDXF.Line();
                line.Type = item.Type.ToString();
                line.Points.Add(StartPoint);
                line.Points.Add(EndPoint);
                list.Add(line);
            }
        }
        #endregion
    }
}
